/*

* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     Smart-Shop开源商城系统/ Java商城-首选电商平台系统 请务必保留此注释头信息
* |     开源地址: https://gitee.com/ningbo-qishan/gruul-mall
* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     可正常分享和学习源码,未经授权 不可商用！
* |     商业版中台购买/开源版商业授权 联系技术客服
* |     官网:  https://www.73app.cn/
* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     Copyright (c) 2016-2999 宁波启山智软科技有限公司
* |     版权所有 ,侵权必究！
* ------------------------------------------------------------------------

*/
package com.medusa.gruul.multi.client.account.service.helper;

import cn.hutool.core.date.DatePattern;
import com.medusa.gruul.common.core.auth.client.helper.ISecurity;
import com.medusa.gruul.common.core.auth.model.User;
import com.medusa.gruul.common.core.auth.model.UserExtends;
import com.medusa.gruul.common.core.auth.model.constant.Keys;
import com.medusa.gruul.common.core.config.Jackson;
import com.medusa.gruul.common.core.helper.AccessToken;
import com.medusa.gruul.common.core.helper.JwtHelper;
import com.medusa.gruul.common.core.helper.RedisKeyHelper;
import com.medusa.gruul.common.core.helper.Token;
import com.medusa.gruul.common.redis.RedisManager;
import com.medusa.gruul.multi.client.account.api.entity.MultiClientAccount;
import com.medusa.gruul.multi.client.account.api.entity.MultiClientAccountData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author 张治保
 * date 2021/12/2
 */
@Slf4j
public class UserHelper {
    private UserHelper(){}

    public static final PasswordEncoder PASSWORD_ENCODER =  new BCryptPasswordEncoder();

    /**
     * 账号信息转user
     */
    public static User toUser(MultiClientAccount account) {
        MultiClientAccountData data = account.getData();
        return new User()
            .setShopUserId(account.getAccountShop().getShopUserId())
            .setShopId(account.getAccountShop().getShopId())
            .setId(account.getId())
            .setUserId(account.getAccountShop().getUserId())
            .setUsername(account.getUsername())
            .setMobile(account.getMobile())
            .setEmail(account.getEmail())
            .setCreateTime(account.getCreateTime())
            .setAuthPlatform(account.getAuth().getAuthPlatform())
            .setNickname(data.getNickname())
            .setGender(data.getGender())
            .setAvatar(data.getAvatar())
            .setLanguage(data.getLanguage())
            .setStatus(account.getStatus())
            .setFirstLoginTime(data.getFirstLoginTime());
    }

    /**
     * 密码加密
     */
    public static String passwordEncrypt(String password,String salt){
        return PASSWORD_ENCODER.encode(password + salt);
    }

    /**
     * 生成AccessToken
     */
    public static AccessToken getTokenByAccount(MultiClientAccount account, UserExtends userExtends){
        User user = UserHelper.toUser(account);
        /*
         * 生成token
         */
        AccessToken token = JwtHelper.token(user);
        /*
         * 更新缓存相关数据
         */
        cache(token,userExtends,user.getUserId());
        return token;
    }


    /**
     * 缓存用户配置信息
     * @param accessToken 用户token信息
     * @param userExtends 用户额外信息
     * @param userId 用户id
     */
    private static void cache(AccessToken accessToken,UserExtends userExtends,String userId){
        Token value = accessToken.getToken();
        /*
         * 计算过期秒数
         */
        int expiredSecond = ((int) accessToken.getTtlTimeUnit().toSeconds(value.getTtl())+10);

        RedisManager redis = RedisManager.getInstance();
        /*
         * 最后修改时间
         */
        redis.set(
            RedisKeyHelper.key(Keys.USER_LAST_MODIFY_TIME, userId),
            LocalDateTime.now().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)),
            expiredSecond
        );
        /*
         * 设置当前平台有效的jti
         */
        String key = RedisKeyHelper.key(Keys.USER_PLATFORM_JTI, ISecurity.platform().must().name(), userId);
        log.info("==========");
        log.info("缓存jti key:{},userId:{}",key,userId);
        redis.set(
            key,
            value.getJti(),
            expiredSecond
        );
        /*
         * 设置额外信息
         */
        redis.set(
            RedisKeyHelper.key(Keys.USER_EXTENDS,userId ),
            Jackson.writeValueAsString(userExtends),
            expiredSecond
        );
    }

}
